<template>
    <Dialog :title="comInfo.name" :show="true" @close="cancel" :width="380" :height="450" :left="uiLeft" :top="uiTop">
        <div class="box">
            <!-- 功能按钮 -->
            <div class="cimrts-menu">
                <FucMenuList :menuList="materailsMenuList" @clickComponent="clickComponent" :isDisabled="false"
                    :isChecked="true" />
            </div>
            <div class="lib-content" ref="containerRef">
                <div v-for="(item, index) in materailsListsRef" :key="index" @mousedown="currentChange(item)"
                    @dragstart="handleDragStart($event, item)" @dragover.prevent class="img-box"
                    @contextmenu.stop.prevent="contexMenuEvent">
                    <div class="img" :class="{ 'is-active': currentMaterailRef.id == item.id }">
                        <img v-if="item.thumb !== null && item.thumb !== undefined && item.thumb !== ''"
                            :src="`data:image/jpeg;base64,${item.thumb}`" alt="">
                        <!-- <img v-else :src="imgUrl" alt=""> -->
                         <div class="not-img" v-else></div>
                    </div>
                    <el-input v-model="item.name"
                        v-show="(isHighlightRef == 'rename' && currentMaterailRef.id == item.id)"
                        @blur="($event: any) => rename(item, $event)" @keydown="keydown" />
                    <div class="name" :title="item.name"
                        v-if="(isHighlightRef != 'rename' || currentMaterailRef.id != item.id)">{{ item.name }} </div>

                </div>
            </div>
        </div>
    </Dialog>
    <ContextMenuCom :baseItems="menuContent"></ContextMenuCom>

    <!-- 动态渲染组件 -->
    <div v-for="(comp, index) in components" :key="comp.id">
        <component :is="comp.type" :id="comp.id" :title="comp.title" :currentMaterail="comp.currentMaterail"
            @cancel="removeMaterailsPanel" @confirm="confirm" @dragEvent="dragEvent" />
    </div>
    <TooltipCom v-if="currentDialog == 'delete'" :content="'确定删除吗？'" :title="'删除'" :isVisible="true"
        @close="currentDialog = ''" @confirm="deleteConfirm" />
</template>
<script setup lang="ts">
import Dialog from "@/components/Dialog.vue";
import { onMounted, ref, onBeforeUnmount, computed, watch, shallowRef, nextTick } from "vue";
import { getProjectManager } from "@/scripts/getProjectManager";
import {
    createVueDisposer,
    toVR,
} from "earthsdk-ui";
import { materailsMenuList } from "@/scripts/menu/cimrts/materailsMenuList";
import { ElMessage } from "element-plus";
import TooltipCom from "@/components/common/TooltipCom.vue";
import FucMenuList from "@/components/common/FucMenuList.vue";
import MaterailsManagerPanel from "@/components/propPanel/cimrts/MaterailsManagerPanel.vue";
import ContextMenuCom from "@/components/common/ContextMenuCom.vue";
import { reqCreatethumb } from "../../api";
import loading from "../../api/loading";
const props = withDefaults(defineProps<{ comInfo: any }>(), {});
const emits = defineEmits(["cancel"]);
const cancel = () => {
    emits("cancel", props.comInfo.id);
    objm.cimrtsManager.absorbEvent.emit(false);
};
const uiLeft = ref(document.body.clientWidth - 10 - 380)
const uiTop = ref(60);
const menuContent = ref<Array<any>>([])

const d = createVueDisposer(onBeforeUnmount);
const objm = getProjectManager();
const materailsManager = objm.cimrtsManager.materailsManager as any

const activeViewerRef = toVR<any>(d, [objm, "activeViewer"])

const imgUrl = new URL("../../assets/cimrts/baseInfo/copy.png", import.meta.url).href

watch(activeViewerRef, () => {
    if (!activeViewerRef.value) return;
    const item = materailsMenuList.value.find((i: any) => i.id = "absorb") as any
    if (activeViewerRef.value.typeName == "ESUeViewer") {
        item.isDisabled = true
    } else {
        item.isDisabled = false
    }
}, { immediate: true })

const isHighlightRef = toVR<string>(d, [materailsManager, "isHighlight"])
// 材质列表
const materailsListsRef = toVR<any>(d, [materailsManager, "materailsLists"])
// 当前选中的材质
const currentMaterailRef = toVR<any>(d, [materailsManager, "currentMaterial"])
// 定位的参数
const scrollParam = toVR<any>(d, [materailsManager, "scrollParam"])

// 当前打开的弹框组件
const currentDialog = ref<undefined | string>(undefined);

// 检测材质名称长度
function isLongString(str: string) {
    /**
     * 判断传入的字符串长度是否大于100
     * 
     * @param {string} str - 要检查的字符串
     * @returns {boolean} 字符串长度大于100时返回true，否则返回false
     */
    if (typeof str !== 'string') {
        // 如果传入的不是字符串类型，将其转换为字符串
        if (str === null || str === undefined) return false;
        str = String(str);
    }

    return str.length > 100;
}

//生成缩略图
const showThumb = async (id: string) => {
    try {
        const data = {
            tileServiceName: objm.cimrtsManager.tileServiceName,
            materialId: id,
        }
        const res = await reqCreatethumb(data)
        // @ts-ignore
        if (res.status !== 'ok') {
            loading.closeLoading()
            ElMessage({
                message: "生成材质缩略图失败",
                type: 'error',
            })
        }
        ElMessage.success('生成材质缩略图成功')
        loading.closeLoading()

        await materailsManager.getMaterialList()
    } catch (error) {
        loading.closeLoading()
        console.error(error)
    }

}

// 克隆
const clone = async () => {
    const param = {
        "datasetName": currentMaterailRef.value.dataset,
        "name": currentMaterailRef.value.name,
        "param": currentMaterailRef.value.param,
        "thumb": currentMaterailRef.value.thumb
    }
    if (isLongString(currentMaterailRef.value.name)) {
        ElMessage.warning("材质名称过长，超出最大长度限制")
        return;
    }
    await materailsManager.cloneMaterial(param);
    await materailsManager.getMaterialList()
    currentMaterailRef.value = materailsListsRef.value[materailsManager.materailsLists.length - 1];
    // 计算当前索引
    scrollParam.value.currentIndex = materailsListsRef.value.findIndex((item: any) => item.id == currentMaterailRef.value.id)
    // 目标行
    scrollParam.value.currentRow = Math.floor(scrollParam.value.currentIndex / scrollParam.value.itemsPerRow)
    // 滚动距离
    const scrollTop = scrollParam.value.currentRow * scrollParam.value.itemHeight
    containerRef.value.scrollTo({ top: scrollTop, behavior: 'smooth' })
    materailsMenuList.value.map((i: any) => i.status = "none")
}
// 删除
const delete2 = async () => {
    currentDialog.value = "delete"
    materailsMenuList.value.map((i: any) => i.status = "none")
}
// 重命名 input 聚焦
const renameFocus = async () => {
    const ipt = containerRef.value.querySelectorAll(".el-input__inner")
    const currentIndex = materailsListsRef.value.findIndex((item: any) => item.id == currentMaterailRef.value.id)
    nextTick(() => {
        ipt[currentIndex].focus()
    })
}

// 按下回车 重命名input失去焦点
const keydown = (event: any) => {
    if (event.code == "Enter") {
        const ipt = containerRef.value.querySelectorAll(".el-input__inner")
        const currentIndex = materailsListsRef.value.findIndex((item: any) => item.id == currentMaterailRef.value.id)
        nextTick(() => {
            ipt[currentIndex].blur()
        })
    }
}

// 编辑
const edit = async () => {
    const flag = components.value.find((item: any) => item.id == currentMaterailRef.value.id)
    if (flag) {
        ElMessage({
            message: '该材质编辑器已存在',
            type: 'warning',
        })
    } else {
        createMaterailsPanel(currentMaterailRef.value)
    }
}

// 鼠标点击组件
const clickComponent = async (item: any) => {
    objm.cimrtsManager.absorbEvent.emit(false);
    isHighlightRef.value = item.id;
    if (item.id != "absorb") {
        if (!Object.keys(currentMaterailRef.value).length) {
            ElMessage.warning("请先选择材质");
            isHighlightRef.value = ""
            materailsMenuList.value.map((i: any) => i.status = "none")
            return;
        }
        if (item.id == "clone") {
            await clone()
            return;
        }
        if (item.id == "delete") {
            delete2()
            return;
        }
        if (item.id == "rename") {
            renameFocus()
            return;
        }
        if (item.id == "edit") {
            edit()
            return;
        }
    } else {
        if (item.status == "active") {
            objm.cimrtsManager.absorbEvent.emit(false);
        } else {
            objm.cimrtsManager.absorbEvent.emit(true);
        }
    }
    item.status != "active" ? item.status = "active" : item.status = "none";
    if (item.status == "none") {
        isHighlightRef.value = ''
    }

}

const contexMenuEvent = () => {//树内右键暴露出来的事件
    const baseItems: Array<any> = [
        {
            text: "重命名",
            keys: "",
            func: () => {
                isHighlightRef.value = "rename"
                renameFocus()
            },
        },
        {
            text: "编辑",
            keys: "",
            func: () => {
                edit()
            },
        },
        {
            text: "克隆",
            keys: "",
            func: () => {
                clone()
            },
        },
        {
            text: "删除",
            keys: "",
            func: () => {
                delete2()
            },
        },
    ];
    menuContent.value = baseItems
}

// 删除 确定按钮
const deleteConfirm = async () => {
    const param = {
        "tileServiceName": objm.cimrtsManager.tileServiceName,
        "materialId": currentMaterailRef.value.id,
    }
    await materailsManager.deleteMaterial(param);
    await materailsManager.getMaterialList()
    currentMaterailRef.value = {}
    currentDialog.value = ""
}

// 选中材质
const currentChange = async (item: any) => {
    if (item.thumb !== null && item.thumb !== undefined && item.thumb !== '') {

    } else {
        await showThumb(item.id)
    }
    currentMaterailRef.value = item
    if (isHighlightRef.value == "rename") {
        const ipt = containerRef.value.querySelectorAll(".el-input__inner")
        const currentIndex = materailsListsRef.value.findIndex((item: any) => item.id == currentMaterailRef.value.id)
        nextTick(() => {
            ipt[currentIndex].focus()
        })
    }
}

// 重命名
const rename = async (item: any, event: any) => {
    const param = {
        "tileServiceName": objm.cimrtsManager.tileServiceName,
        "materialId": item.id,
        "newName": event.target.value
    }
    if (isLongString(event.target.value)) {
        ElMessage.warning("材质名称过长，超出最大长度限制")
        return;
    }
    await materailsManager.renameMaterial(param)
    await materailsManager.getMaterialList()
    isHighlightRef.value = ''
    materailsMenuList.value.map((i: any) => i.status = "none")
}

const components = ref<any>([])

// 创建材质编辑器面板
const createMaterailsPanel = async (item: any) => {
    components.value.push({
        id: currentMaterailRef.value.id,
        type: shallowRef(MaterailsManagerPanel), // 组件名
        title: `材质编辑器-${currentMaterailRef.value.name}`, // 标题
        currentMaterail: currentMaterailRef.value,
    });
}

// 删除材质编辑器窗口
const removeMaterailsPanel = async (id: string) => {
    const index = components.value.findIndex((item: any) => item.id == id)
    components.value.splice(index, 1);
}

const dragEvent = (id: string) => {
    const item = components.value.find((item: any) => item.id == id)
    item.currentMaterail = currentMaterailRef.value
}

// 材质编辑器 确定按钮
const confirm = async () => {
    await materailsManager.getMaterialList()
    // currentMaterailRef.value = materailsManager.materailsLists.find((i: any) => i.id === currentMaterailRef.value.id)
    currentMaterailRef.value = {}
    components.value = []
    objm.cimrtsManager.eSRtsTileset.refresh();

}

// 拖拽事件
const handleDragStart = (event: any, item: any) => {
    const data = {
        dataset: item.dataset,
        id: item.id,
        param: item.param
    }
    event.dataTransfer?.setData('text/plain', JSON.stringify(data))
    materailsMenuList.value.map((i: any) => i.status = "none")
    isHighlightRef.value = ''
    objm.cimrtsManager.absorbEvent.emit(false);
}
const containerRef = ref<any>(null)

onMounted(async () => {
    await materailsManager.init()
    nextTick(() => {
        materailsManager.initResizeObserver(containerRef.value);
    })
})
onBeforeUnmount(() => {
    materailsManager.clear()
    materailsMenuList.value.map((i: any) => i.status = "none")
    objm.cimrtsManager.absorbEvent.emit(false);
})
</script>

<style scoped>
.box {
    box-sizing: border-box;
    width: 100%;
    height: 100%;
}

.cimrts-menu {
    background-color: #f0f0f0;
    width: calc(100%);
    height: 40px;
    display: flex;
    align-items: center;
}

.lib-content {
    max-height: calc(100% - 50px);
    padding: 5px;
    display: flex;
    flex-wrap: wrap;
    overflow-y: auto;
}

.lib-content2 {
    max-height: 240px;
    padding: 5px;
    display: flex;
    flex-wrap: wrap;
    overflow-y: auto;
}

.img-box {
    display: flex;
    flex-direction: column;
    gap: 8px;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    margin-right: 10px;
    margin-bottom: 5px;

}

.img {
    box-sizing: border-box;
    width: 80px;
    height: 80px;
    padding: 5px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.img img {
    width: 70px;
    height: 70px;
}
.not-img{
    width: 70px;
    height: 70px;
    background: url(../../assets/cimrts/materailsManager/preview.svg) no-repeat;
    background-size: 100% 100%;
}
.not-img:hover{
    background: url(../../assets/cimrts/materailsManager/preview_hover.svg) no-repeat;
    background-size: 100% 100%;
}


.name {
    width: 80px;
    overflow: hidden;
    height: 26px;
    white-space: nowrap;
    text-overflow: ellipsis;
    padding: 2px 0;
    text-align: center;
}

.is-active {
    border: 2px solid #409eff;
}


:deep(.el-input__wrapper) {
    box-sizing: border-box;
    width: 80px;
    height: 30px;
    padding: 5px;
}

:deep(.el-input__inner) {
    text-align: center;
}
</style>